from flask import Flask, render_template, redirect, url_for, request
import pymysql
import base64
from PIL import Image
from io import BytesIO
from flask import jsonify
from gmssl.sm4 import CryptSM4, SM4_ENCRYPT, SM4_DECRYPT

app = Flask(__name__)

db_params = {
    'host': 'localhost',
    'user': 'root',
    'password': '123456',
    'database': 'encryption_system',
    'charset': 'utf8mb4'  # 添加charset字段并设置为utf8mb4
}


@app.route('/')
def index():
    return render_template('login.html')


@app.route('/login', methods=['POST'])
def login():
    username = request.form['username']
    password = request.form['password']
    identity = request.form['selected_identity']  # 获取隐藏的身份选择值

    # 数据库连接
    connection = pymysql.connect(**db_params)
    try:
        # 创建游标对象
        with connection.cursor() as cursor:
            # 执行查询语句
            sql = "SELECT * FROM users WHERE username=%s AND password=%s"
            cursor.execute(sql, (username, password))

            # 获取查询结果
            result = cursor.fetchone()

            if result:
                # 验证通过，根据用户选择的身份重定向到相应页面
                if identity == 'radiologist':
                    return redirect(url_for('radiologist'))
                elif identity == 'outpatient_doctor':
                    return redirect(url_for('outpatient_doctor'))
                elif identity == 'admin':
                    return redirect(url_for('admin'))
            else:
                # 验证失败，返回登录页面并提供错误消息
                error_msg = '用户名或者密码错误'
                return render_template('login.html', error_msg=error_msg, username='')
    finally:
        # 关闭数据库连接
        connection.close()


# 放射科医生的页面
@app.route('/radiologist')
def radiologist():
    return render_template('radiologist_dashboard.html')


# 放射科病人页面
@app.route('/Patient1_Information')
def Patient1_Information():
    return render_template('Patient1_Information.html')

@app.route('/Patient2_Information')
def Patient2_Information():
    return render_template('Patient2_Information.html')


@app.route('/Patient3_Information')
def Patient3_Information():
    return render_template('Patient3_Information.html')


@app.route('/Patient4_Information')
def Patient4_Information():
    return render_template('Patient4_Information.html')


@app.route('/encrypt_patient1', methods=['POST'])
def encrypt_patient1():
    key = request.form['key']
    print(key)
    rounds = int(request.form['rounds'])
    print(rounds)

    # 加载患者图像
    image_path = "static/Patient1.jpg"
    image = Image.open(image_path)

    # Arnold加密
    for _ in range(rounds):
        image = image.convert("L")  # 转换为灰度图像
        width, height = image.size
        temp_image = Image.new("L", (width, height))

        for y in range(height):
            for x in range(width):
                new_x = (x + y) % width
                new_y = (x + 2 * y) % height
                temp_image.putpixel((new_x, new_y), image.getpixel((x, y)))

        image = temp_image

    # 使用SM4加密轮数
    sm4_cipher = CryptSM4()
    sm4_cipher.set_key(key.encode(), SM4_ENCRYPT)
    encrypted_rounds = sm4_cipher.crypt_ecb(bytes(str(rounds).zfill(16), 'utf-8'))
    print(encrypted_rounds)

    # 保存加密后的图像
    encrypted_image_path = "static/Encrypted_patient1.jpg"
    image.save(encrypted_image_path)

    # 将加密后的图像转换为字节流
    output_buffer = BytesIO()
    image.save(output_buffer, format="JPEG")
    encrypted_image_data = base64.b64encode(output_buffer.getvalue()).decode('utf-8')

    print(encrypted_rounds.hex())

    return jsonify({
        'encrypted_image': encrypted_image_data,
        'encrypted_rounds': encrypted_rounds.hex()
    })


@app.route('/encrypt_patient2', methods=['POST'])
def encrypt_patient2():
    key = request.form['key']
    print(key)
    rounds = int(request.form['rounds'])
    print(rounds)

    # 加载患者图像
    image_path = "static/Patient2.jpg"
    image = Image.open(image_path)

    # Arnold加密
    for _ in range(rounds):
        image = image.convert("L")  # 转换为灰度图像
        width, height = image.size
        temp_image = Image.new("L", (width, height))

        for y in range(height):
            for x in range(width):
                new_x = (x + y) % width
                new_y = (x + 2 * y) % height
                temp_image.putpixel((new_x, new_y), image.getpixel((x, y)))

        image = temp_image

    # 使用SM4加密轮数
    sm4_cipher = CryptSM4()
    sm4_cipher.set_key(key.encode(), SM4_ENCRYPT)
    encrypted_rounds = sm4_cipher.crypt_ecb(bytes(str(rounds).zfill(16), 'utf-8'))
    print(encrypted_rounds)

    # 保存加密后的图像
    encrypted_image_path = "static/Encrypted_patient2.jpg"
    image.save(encrypted_image_path)

    # 将加密后的图像转换为字节流
    output_buffer = BytesIO()
    image.save(output_buffer, format="JPEG")
    encrypted_image_data = base64.b64encode(output_buffer.getvalue()).decode('utf-8')

    print(encrypted_rounds.hex())

    return jsonify({
        'encrypted_image': encrypted_image_data,
        'encrypted_rounds': encrypted_rounds.hex()
    })


@app.route('/encrypt_patient3', methods=['POST'])
def encrypt_patient3():
    key = request.form['key']
    print(key)
    rounds = int(request.form['rounds'])
    print(rounds)

    # 加载患者图像
    image_path = "static/Patient3.jpg"
    image = Image.open(image_path)

    # Arnold加密
    for _ in range(rounds):
        image = image.convert("L")  # 转换为灰度图像
        width, height = image.size
        temp_image = Image.new("L", (width, height))

        for y in range(height):
            for x in range(width):
                new_x = (x + y) % width
                new_y = (x + 2 * y) % height
                temp_image.putpixel((new_x, new_y), image.getpixel((x, y)))

        image = temp_image

    # 使用SM4加密轮数
    sm4_cipher = CryptSM4()
    sm4_cipher.set_key(key.encode(), SM4_ENCRYPT)
    encrypted_rounds = sm4_cipher.crypt_ecb(bytes(str(rounds).zfill(16), 'utf-8'))
    print(encrypted_rounds)

    # 保存加密后的图像
    encrypted_image_path = "static/Encrypted_patient3.jpg"
    image.save(encrypted_image_path)

    # 将加密后的图像转换为字节流
    output_buffer = BytesIO()
    image.save(output_buffer, format="JPEG")
    encrypted_image_data = base64.b64encode(output_buffer.getvalue()).decode('utf-8')

    print(encrypted_rounds.hex())

    return jsonify({
        'encrypted_image': encrypted_image_data,
        'encrypted_rounds': encrypted_rounds.hex()
    })


@app.route('/encrypt_patient4', methods=['POST'])
def encrypt_patient4():
    key = request.form['key']
    print(key)
    rounds = int(request.form['rounds'])
    print(rounds)

    # 加载患者图像
    image_path = "static/Patient4.jpg"
    image = Image.open(image_path)

    # Arnold加密
    for _ in range(rounds):
        image = image.convert("L")  # 转换为灰度图像
        width, height = image.size
        temp_image = Image.new("L", (width, height))

        for y in range(height):
            for x in range(width):
                new_x = (x + y) % width
                new_y = (x + 2 * y) % height
                temp_image.putpixel((new_x, new_y), image.getpixel((x, y)))

        image = temp_image

    # 使用SM4加密轮数
    sm4_cipher = CryptSM4()
    sm4_cipher.set_key(key.encode(), SM4_ENCRYPT)
    encrypted_rounds = sm4_cipher.crypt_ecb(bytes(str(rounds).zfill(16), 'utf-8'))
    print(encrypted_rounds)

    # 保存加密后的图像
    encrypted_image_path = "static/Encrypted_patient4.jpg"
    image.save(encrypted_image_path)

    # 将加密后的图像转换为字节流
    output_buffer = BytesIO()
    image.save(output_buffer, format="JPEG")
    encrypted_image_data = base64.b64encode(output_buffer.getvalue()).decode('utf-8')

    print(encrypted_rounds.hex())

    return jsonify({
        'encrypted_image': encrypted_image_data,
        'encrypted_rounds': encrypted_rounds.hex()
    })



# 门诊医生的页面
@app.route('/outpatient_doctor')
def outpatient_doctor():
    return render_template('outpatient_doctor_dashboard.html')


@app.route('/decrypt_image_patient1', methods=['POST'])
def decrypt_image_patient1():
    decryption_key = request.form['key']
    encrypted_rounds_hex = request.form['encrypted_rounds']

    # Convert encrypted rounds from hex to bytes
    encrypted_rounds_bytes = bytes.fromhex(encrypted_rounds_hex)

    # Use decryption key to decrypt rounds
    sm4_cipher = CryptSM4()
    sm4_cipher.set_key(decryption_key.encode(), SM4_DECRYPT)
    decrypted_rounds_data = sm4_cipher.crypt_ecb(encrypted_rounds_bytes)

    try:
        rounds = int(decrypted_rounds_data.decode('utf-8').strip())
        print("Decrypted Rounds:", rounds)
    except ValueError:
        return jsonify({'error': '解密失败。无效的密钥或损坏的数据!'}), 400

    encrypted_rounds=rounds

    # 加载患者图像
    image_path = "static/Encrypted_patient1.jpg"
    image = Image.open(image_path)

    width, height = image.size
    for _ in range(encrypted_rounds):
        temp_image = Image.new("L", (width, height))
        for y in range(height):
            for x in range(width):
                new_x = (2 * x - y) % width
                new_y = (-x + y) % height
                temp_image.putpixel((new_x, new_y), image.getpixel((x, y)))
        image = temp_image

    output_buffer = BytesIO()
    image.save(output_buffer, format="JPEG")
    decrypted_image_data = base64.b64encode(output_buffer.getvalue()).decode('utf-8')

    patient_info = {
        'name': '李四',
        'gender': '男',
        'age': '45',
        'condition': '骨组织微结构破坏、骨脆性增加，骨质疏松症'
    }

    return jsonify({
        'decrypted_image': decrypted_image_data,
        'patient_name': patient_info['name'],
        'patient_gender': patient_info['gender'],
        'patient_age': patient_info['age'],
        'patient_condition': patient_info['condition'],
        'decrypted_rounds': rounds  # Return decrypted rounds to frontend
    })


@app.route('/decrypt_image_patient2', methods=['POST'])
def decrypt_image_patient2():
    decryption_key = request.form['key']
    encrypted_rounds_hex = request.form['encrypted_rounds']

    # Convert encrypted rounds from hex to bytes
    encrypted_rounds_bytes = bytes.fromhex(encrypted_rounds_hex)

    # Use decryption key to decrypt rounds
    sm4_cipher = CryptSM4()
    sm4_cipher.set_key(decryption_key.encode(), SM4_DECRYPT)
    decrypted_rounds_data = sm4_cipher.crypt_ecb(encrypted_rounds_bytes)

    try:
        rounds = int(decrypted_rounds_data.decode('utf-8').strip())
        print("Decrypted Rounds:", rounds)
    except ValueError:
        return jsonify({'error': '解密失败。无效的密钥或损坏的数据!'}), 400

    encrypted_rounds=rounds

    # 加载患者图像
    image_path = "static/Encrypted_patient2.jpg"  # 根据实际情况修改路径
    image = Image.open(image_path)

    width, height = image.size
    for _ in range(encrypted_rounds):
        temp_image = Image.new("L", (width, height))
        for y in range(height):
            for x in range(width):
                new_x = (2 * x - y) % width
                new_y = (-x + y) % height
                temp_image.putpixel((new_x, new_y), image.getpixel((x, y)))
        image = temp_image

    output_buffer = BytesIO()
    image.save(output_buffer, format="JPEG")
    decrypted_image_data = base64.b64encode(output_buffer.getvalue()).decode('utf-8')

    patient_info = {
        'name': '张三',
        'gender': '女',
        'age': '60',
        'condition': '阿尔茨海默病早期，出现记忆力减退、语言表达困难，部分日常生活能力下降'
    }

    return jsonify({
        'decrypted_image': decrypted_image_data,
        'patient_name': patient_info['name'],
        'patient_gender': patient_info['gender'],
        'patient_age': patient_info['age'],
        'patient_condition': patient_info['condition'],
        'decrypted_rounds': rounds  # Return decrypted rounds to frontend
    })


@app.route('/decrypt_image_patient3', methods=['POST'])
def decrypt_image_patient3():
    decryption_key = request.form['key']
    encrypted_rounds_hex = request.form['encrypted_rounds']

    # Convert encrypted rounds from hex to bytes
    encrypted_rounds_bytes = bytes.fromhex(encrypted_rounds_hex)

    # Use decryption key to decrypt rounds
    sm4_cipher = CryptSM4()
    sm4_cipher.set_key(decryption_key.encode(), SM4_DECRYPT)
    decrypted_rounds_data = sm4_cipher.crypt_ecb(encrypted_rounds_bytes)

    try:
        rounds = int(decrypted_rounds_data.decode('utf-8').strip())
        print("Decrypted Rounds:", rounds)
    except ValueError:
        return jsonify({'error': '解密失败。无效的密钥或损坏的数据!'}), 400

    encrypted_rounds=rounds

    # 加载患者图像
    image_path = "static/Encrypted_patient3.jpg"  # 根据实际情况修改路径
    image = Image.open(image_path)

    width, height = image.size
    for _ in range(encrypted_rounds):
        temp_image = Image.new("L", (width, height))
        for y in range(height):
            for x in range(width):
                new_x = (2 * x - y) % width
                new_y = (-x + y) % height
                temp_image.putpixel((new_x, new_y), image.getpixel((x, y)))
        image = temp_image

    output_buffer = BytesIO()
    image.save(output_buffer, format="JPEG")
    decrypted_image_data = base64.b64encode(output_buffer.getvalue()).decode('utf-8')

    patient_info = {
        'name': '王五',
        'gender': '男',
        'age': '35',
        'condition': '重度抑郁症，伴随长期焦虑和失眠，情绪低落、对日常活动失去兴趣，时常有自杀念头'
    }

    return jsonify({
        'decrypted_image': decrypted_image_data,
        'patient_name': patient_info['name'],
        'patient_gender': patient_info['gender'],
        'patient_age': patient_info['age'],
        'patient_condition': patient_info['condition'],
        'decrypted_rounds': rounds  # Return decrypted rounds to frontend
    })


@app.route('/decrypt_image_patient4', methods=['POST'])
def decrypt_image_patient4():
    decryption_key = request.form['key']
    encrypted_rounds_hex = request.form['encrypted_rounds']

    # Convert encrypted rounds from hex to bytes
    encrypted_rounds_bytes = bytes.fromhex(encrypted_rounds_hex)

    # Use decryption key to decrypt rounds
    sm4_cipher = CryptSM4()
    sm4_cipher.set_key(decryption_key.encode(), SM4_DECRYPT)
    decrypted_rounds_data = sm4_cipher.crypt_ecb(encrypted_rounds_bytes)

    try:
        rounds = int(decrypted_rounds_data.decode('utf-8').strip())
        print("Decrypted Rounds:", rounds)
    except ValueError:
        return jsonify({'error': '解密失败。无效的密钥或损坏的数据!'}), 400

    encrypted_rounds=rounds

    # 加载患者图像
    image_path = "static/Encrypted_patient4.jpg"  # 根据实际情况修改路径
    image = Image.open(image_path)

    width, height = image.size
    for _ in range(encrypted_rounds):
        temp_image = Image.new("L", (width, height))
        for y in range(height):
            for x in range(width):
                new_x = (2 * x - y) % width
                new_y = (-x + y) % height
                temp_image.putpixel((new_x, new_y), image.getpixel((x, y)))
        image = temp_image

    output_buffer = BytesIO()
    image.save(output_buffer, format="JPEG")
    decrypted_image_data = base64.b64encode(output_buffer.getvalue()).decode('utf-8')

    patient_info = {
        'name': '赵六',
        'gender': '女',
        'age': '25',
        'condition': '脑卒中恢复期，左侧肢体无力，言语困难，需进行长期康复治疗'
    }

    return jsonify({
        'decrypted_image': decrypted_image_data,
        'patient_name': patient_info['name'],
        'patient_gender': patient_info['gender'],
        'patient_age': patient_info['age'],
        'patient_condition': patient_info['condition'],
        'decrypted_rounds': rounds  # Return decrypted rounds to frontend
    })

# 放射科病人页面
@app.route('/decrypted_patient1')
def decrypted_patient1():
    return render_template('decrypted_patient1.html')

# 放射科病人页面
@app.route('/decrypted_patient2')
def decrypted_patient2():
    return render_template('decrypted_patient2.html')

# 放射科病人页面
@app.route('/decrypted_patient3')
def decrypted_patient3():
    return render_template('decrypted_patient3.html')

# 放射科病人页面
@app.route('/decrypted_patient4')
def decrypted_patient4():
    return render_template('decrypted_patient4.html')


# 系统管理员的页面
@app.route('/admin')
def admin():
    return render_template('admin_dashboard.html')


if __name__ == '__main__':
    app.run()